local servantLib = require "packages/activities/servantLib"
local U = require "packages/utility/utility"

--- add skill
---@param player ServerPlayer
---@param skillName string
local addRoleModSkills = function(player, skillName)
  local room = player.room
  local skill = Fk.skills[skillName]
  if not skill then
    fk.qCritical("Skill: "..skillName.." doesn't exist!")
    return
  end
  if skill.lordSkill and (player.role ~= "lord" or #room.players < 5) then
    return
  end

  if #skill.attachedKingdom > 0 and not table.contains(skill.attachedKingdom, player.kingdom) then
    return
  end

  room:handleAddLoseSkills(player, skillName, nil, false)
end

--- add ingots
---@param player ServerPlayer
---@param num integer
local function addIngots(player, num)
  local room = player.room
  if num > 0 then
    room:addPlayerMark(player, "@!ingots", num)
  else
    room:removePlayerMark(player, "@!ingots", -num)
  end
end

--- get ingots' num
---@param player ServerPlayer
local function getIngotsNum(player)
  return player:getMark("@!ingots")
end

--- add general into servant area
---@param player ServerPlayer
---@param gName string
local function addServant(player, gName)
  local room = player.room
  local servant_pile = room:getTag("ServantPile")
  for i, s in ipairs(servant_pile) do
    if s[1] == gName then
      table.remove(servant_pile, i)
      break
    end
  end
  local servants = player:getTableMark( "@&conscript_servants")
  table.insert(servants, gName)
  room:setPlayerMark(player, "@&conscript_servants", servants)
end

--- load data
---@param player ServerPlayer
---@param chosen table
local function addData(player, chosen)
  local gName, cost = chosen[1], chosen[2]
  addIngots(player, -cost)
  addServant(player, gName)
  for _, sName in ipairs(Fk.generals[gName]:getSkillNameList()) do
    addRoleModSkills(player, sName)
  end
end

  -- 模式逻辑
local conscript_getLogic = function()
  ---@class GameLogic
  local conscript_logic = GameLogic:subclass("conscript_logic")
  -- 皮套自备
  function conscript_logic:chooseGenerals()
    local room = self.room
    local lord = room:getLord()
    room.current = lord
    local players = room.players
    for _, p in ipairs(players) do
      local avatar = p._splayer:getAvatar()
      if avatar == "anjiang" then avatar = "guanyu" end
      local avatar_general = Fk.generals[avatar] or Fk.generals["guanyu"]
      room:setPlayerGeneral(p, avatar_general.name, true)
      room:broadcastProperty(p, "general")
      room:setPlayerProperty(p, "shield", 0)
      if p == lord then
        room:setPlayerProperty(p, "maxHp", 5)
        room:setPlayerProperty(p, "hp", 5)
        addIngots(p, 300)
      else
        room:setPlayerProperty(p, "maxHp", 4)
        room:setPlayerProperty(p, "hp", 4)
        addIngots(p, 200)
      end
    end
    room:doBroadcastNotify("ShowToast", Fk:translate("conscript_intro"))
  end
  -- 体力初始化（上面已经做了）
  function conscript_logic:broadcastGeneral()

  end
  -- 技能初始化
  function conscript_logic:attachSkillToPlayers()
    local room = self.room
    local players = room.players
    local gNum = room.settings.generalNum
    -- create servant pile
    local servantLibBeta = table.simpleClone(servantLib)
    local servantPile = table.map(servantLibBeta, function (spec)
      return {spec.name, spec.cost}
    end)
    room:setTag("ServantPile", servantPile)
    -- servants!
    local servants = table.random(room:getTag("ServantPile"), #players *gNum)
    local req = Request:new(players, "CustomDialog")
    req.focus_text = "#conscript_rule"
    for i, p in ipairs(players) do -- conscript!
      local request_data = {
        path = "packages/activities/qml/conscript.qml",
        data = { table.slice(servants, (i -1) *gNum +1, i *gNum +1), getIngotsNum(p) }
      }
      req:setData(p, request_data)
      req:setDefaultReply(p, "Cancel")
    end

    for _, p in ipairs(players) do
      local chosens = req:getResult(p)
      if chosens ~= "Cancel" then
        for _, chosen in ipairs(chosens) do
          addData(p, chosen)
        end
      end
    end
  end

  return conscript_logic
end

  -- 模式规则
local conscript_rule = fk.CreateTriggerSkill{
  name = "#conscript_rule",
  priority = 0.001,
  refresh_events = {fk.GameStart, fk.Damage, fk.Damaged, fk.TurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      room:setBanner("@[:]mode_desc", "conscript_desc")
    elseif event == fk.Damage then -- 造成伤害获得元宝
      if target == player then
        addIngots(player, 20 *data.damage)
      end
    elseif event == fk.Damaged then
      if target == player then
        addIngots(player, 10*data.damage)
      end
    else -- 回合开始招募
      local servants = table.random(room:getTag("ServantPile"), room.settings.generalNum)
      local chosens = room:askForCustomDialog(player, self.name, "packages/activities/qml/conscript.qml", { servants, getIngotsNum(player) } )
      if chosens ~= "" then
        chosens = json.decode(chosens)
        if chosens ~= "Cancel" then
          for _, chosen in ipairs(chosens) do
            addData(player, chosen)
          end
        end
      end
    end
  end,
}
Fk:addSkill(conscript_rule)

--人数限制
local conscript_mode = fk.CreateGameMode{
  name = "conscript_mode",
  minPlayer = 2,
  maxPlayer = 8,
  rule = conscript_rule,
  logic = conscript_getLogic,
  surrender_func = function(self, playedTime)
    return Fk.game_modes["aaa_role_mode"].surrenderFunc(self, playedTime)
  end,
}

local desc_conscript = [[
  # 征兵募贤 模式简介

  ---

  ## 游戏规则
  
  身份、游戏目标、击杀奖惩与军争模式一致

  但所有角色以自己的头像为武将，但没有技能。所有角色的体力上限、体力值被调整到4点、护甲归零。

  ---
  
  ## 随从

  本模式每名武将都根据强度增加了相应的费用，每名武将都可以被场上角色招募。

  随从：当一名武将被角色招募后，将成为该角色的随从，其技能为该角色所用(主公技除外，角色身份为主公时才拥有)。

  随从区：每名角色拥有一个随从区，是放置随从的区域。

  ---

  ## 招募

  招募：指选择一张随从牌，并支付对应的费用，将之置入随从区的行为。

  元宝：是用于支付费用的道具，游戏开始时会给予一定数量（每名角色200，主公多100），
      可以通过造成伤害（1点对应20元宝）、承受伤害获得（1点对应10元宝）。

  征召：指随机观看一定数量的随从牌（其实就是选将数），招募其中任意名随从的行为。

  游戏开始时，所有角色执行一次同时进行的“征召”；每名角色的回合开始时，其单独执行“征召”。

]]

Fk:loadTranslationTable{
  ["conscript_mode"] = "征兵募贤",
  [":conscript_mode"] = desc_conscript,
  ["#conscript_rule"] = "征召",
  ["conscript_intro"] = "征兵募贤, 优劣得所。<br/>运用组合的智慧击败对手吧！",

  ["@&conscript_servants"] = "随从区",
  ["@!ingots"] = "元宝",

  ["conscript_desc"] = "征兵募贤",
  [":conscript_desc"] = [[
  <br>♦本模式每名武将牌都根据强度增加了相应的费用。
  <br>♦每名武将都可以被你招募。你若相中了一名武将，则可以支付对应费用的元宝，将该武将纳入你的麾下，
      使其成为你的随从，技能为你所用。
  <br>♦回合开始时，你观看一定数量的武将，招募其中任意名武将（不允许透支元宝）。
  ]]
}

return conscript_mode
